<template>
  <teleport to=".chat-box">
    <template v-if="isRender">
      <transition name="noGroup-mark">
        <div class="noGroup-mark flex" v-show="showDialog">
          <transition name="noGroup">
            <div class="noGroup-content" v-show="showDialog">
              <div class="noGroup-content__header">
                <span>添加成员</span>
                <SvgIcon
                  icon-class="close"
                  popper-class="title-close"
                  @click="closeDialog"
                />
              </div>
              <div class="noGroup-content__main">
                <template v-if="showContent">
                  <div class="noGroup-list__title">
                    <div
                      :class="{
                        flex: true,
                        'friend-check': true,
                        isChecked: seleIds.size === noGroupData.length,
                        noChecked: seleIds.size !== noGroupData.length,
                      }"
                      @click="selectAll"
                    >
                      <SvgIcon popper-class="icon-checked" icon-class="check" />
                    </div>
                    全选
                  </div>
                  <el-scrollbar :max-height="350">
                    <ul>
                      <li
                        class="noGroup-list__item"
                        v-for="{ userId, avatar, remark } in noGroupData"
                        :key="userId"
                        @click="selectPart(userId)"
                      >
                        <div
                          :class="{
                            flex: true,
                            'friend-check': true,
                            isChecked: seleIds.has(userId),
                            noChecked: !seleIds.has(userId),
                          }"
                        >
                          <SvgIcon popper-class="icon-checked" icon-class="check" />
                        </div>
                        <img :src="avatar" alt="" @click.stop="openModal(avatar)" />
                        <span :title="remark">{{ remark }}</span>
                      </li>
                    </ul></el-scrollbar
                  >
                  <div class="noGroup-content__footer">
                    <el-button
                      class="footer-cancel"
                      :disabled="isLoading"
                      @click="closeDialog"
                      >取消</el-button
                    >
                    <el-button
                      class="footer-confirm"
                      type="primary"
                      :disabled="isLoading || !seleIds.size"
                      :loading="isLoading"
                      @click="addFriFromGroup"
                      ><template #loading><Loading /></template>确定</el-button
                    >
                  </div>
                  <Modal v-model="showModal">
                    <img class="img-browser" :src="imgSrc" alt="" /> </Modal
                ></template>
                <div class="main-loading" v-else-if="isRequesting">
                  <SvgIcon icon-class="loadingGray" popper-class="loadingIcon spinMess" />
                </div>
                <div class="main-error" v-else-if="isError">
                  请求失败，点击
                  <span @click="getNoGroupData">重试</span>
                </div>
              </div>
            </div>
          </transition>
        </div></transition
      ></template
    ></teleport
  >
</template>

<script lang="ts" setup>
import { ref, watch, nextTick, reactive } from "vue";
import { useFriendPinia } from "@/pinia/friend";
import { useUserPinia } from "@/pinia/user";
import { storeToRefs } from "pinia";
import { ElMessage } from "element-plus";
import Modal from "@/components/ui-components/modal.vue";

const props = withDefaults(
  defineProps<{
    modelValue: boolean;
    group?: string;
  }>(),
  {
    group: "",
  }
);
const emits = defineEmits<{
  (e: "update:modelValue", show: boolean): void;
}>();

const friendStore = useFriendPinia();
const { user } = storeToRefs(useUserPinia());

/**
 * 当前用户查看的图片的url
 */
const imgSrc = ref<string>("");
/**
 * 是否显示模态框
 */
const showModal = ref<boolean>(false);
// 浏览图片时打开模态框
const openModal: (url: string) => void = (url: string): void => {
  imgSrc.value = url;
  showModal.value = true;
};

/**
 * 当前无分组数据
 */
const noGroupData = reactive<
  Array<{
    avatar: string;
    remark: string;
    userId: string;
  }>
>([]);
/**
 * 是否正在请求无分组数据
 */
const isRequesting = ref<boolean>(false);
/**
 * 请求是否出错
 */
const isError = ref<boolean>(false);
/**
 * 是否显示正文内容
 */
const showContent = ref<boolean>(false);

// 请求无分组数据
const getNoGroupData = () => {
  if (!isRequesting.value) {
    if (isError.value) isError.value = false;
    isRequesting.value = true;
    friendStore
      .getNoGroupData()
      .then((data) => {
        isRequesting.value = false;
        if (data.code === 1) {
          noGroupData.push(...data.friendsData);
          showContent.value = true;
        } else isError.value = true;
      })
      .catch(() => {
        isRequesting.value = false;
        isError.value = true;
      });
  }
};

/**
 * 是否显示确认操作的对话框
 */
const isRender = ref<boolean>(false);
/**
 * 是否显示确认操作的对话框的内容
 */
const showDialog = ref<boolean>(false);

watch(
  () => props.modelValue,
  (show: boolean) => {
    if (show) {
      isRender.value = true;
      nextTick(() => {
        showDialog.value = true;
        getNoGroupData();
      });
    } else {
      showDialog.value = false;
      setTimeout(() => {
        isRender.value = false;
        noGroupData.length && noGroupData.splice(0);
        showContent.value = false;
        seleIds.clear();
      }, 300);
    }
  },
  { immediate: true }
);

/**
 * 是否正在发送请求
 */
const isLoading = ref<boolean>(false);

// 是否关闭对话框
const closeDialog = () => {
  if (!isLoading.value && !isRequesting.value) emits("update:modelValue", false);
};

/**
 * 当前用户所勾选的好友账号集合
 */
const seleIds = reactive<Set<string>>(new Set());

// 勾选当前全部好友
const selectAll = () => {
  if (seleIds.size === noGroupData.length) seleIds.clear();
  else for (const { userId } of noGroupData) seleIds.add(userId);
};

// 勾选部分好友
const selectPart = (key: string) => {
  if (seleIds.has(key)) seleIds.delete(key);
  else seleIds.add(key);
};

// 向特定分组添加成员
const addFriFromGroup = () => {
  isLoading.value = true;
  friendStore
    .addFriFromGroup({
      selfId: user.value.userId,
      group: props.group,
      otherIds: [...seleIds],
      isNeed: friendStore.friendsManage.get("groups")!.groups?.get(props.group)
        ?.isRequest,
    })
    .then((code: number) => {
      isLoading.value = false;
      if (code === 1) {
        emits("update:modelValue", false);
        ElMessage({
          type: "success",
          message: "添加成功",
          duration: 1500,
        });
      } else
        ElMessage({
          type: "error",
          message: "添加失败",
          duration: 1500,
        });
    })
    .catch(() => {
      isLoading.value = false;
      ElMessage({
        type: "error",
        message: "添加失败",
        duration: 1500,
      });
    });
};
</script>

<style lang="scss" scoped>
.noGroup {
  &-enter-active,
  &-leave-active {
    transition: transform 0.3s;
  }

  &-enter-from,
  &-leave-to {
    transform: translateY(-30px);
  }

  &-mark {
    position: fixed;
    inset: 0;
    z-index: 1003;
    @include fade(0.25s, ease);
  }

  &-content {
    background-color: #fff;
    width: 270px;
    border-radius: 6px;
    box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.12);

    &__header {
      position: relative;
      padding: 6px 10px 8px;

      span {
        font-size: 12px;
        color: $dimFontCor;
      }

      .title-close {
        position: absolute;
        right: 3%;
        top: 6px;
        color: #909399;
        cursor: pointer;
        transition: color 0.15s;

        &:hover {
          color: #79bbff;
        }
      }
    }

    &__main {
      padding: 10px 0 8px;
      text-align: center;
      color: #333;

      .main {
        &-loading {
          height: 30px;
          margin-bottom: 18px;

          .loadingIcon {
            font-size: 30px;
          }
        }

        &-error {
          height: 30px;
          font-size: 14px;
          margin-bottom: 18px;

          span {
            transition: color 0.2s;

            &:hover {
              cursor: pointer;
              color: rgb(250, 12, 12);
              text-decoration: underline;
            }
          }
        }
      }

      .friend-check {
        @include setWidHei(15px, 15px);
        margin-right: 10%;
        transition: background-color 0.25s;
      }
    }

    &__footer {
      padding: 22px 25px 12px;
      .footer {
        &-cancel {
          width: 35%;
        }

        &-confirm {
          width: 35%;
          margin-left: 30%;
        }
      }
    }
  }

  &-list {
    &__title {
      display: flex;
      align-items: center;
      padding: 0 0 10px 15px;
      font-size: 14px;
    }

    &__item {
      display: flex;
      align-items: center;
      padding: 15px;
      transition: background-color 0.75s;
      font-size: 14px;
      cursor: pointer;

      span {
        display: inline-block;
        max-width: 120px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      &:hover {
        background-color: rgba(154, 152, 152, 0.114);
      }

      img {
        @include setWidHei(38px, 38px);
        border-radius: 50%;
        margin-right: 20px;
        object-fit: cover;
      }
    }
  }
}
</style>
